package version

import (
	"fmt"
	"os"
	"strconv"

	"github.com/spf13/pflag"
)

// 定义了一个 pflag.Value 接口实现类型
type versionValue int

var _ pflag.Value = (*versionValue)(nil)

const (
	VersionFalse versionValue = 0
	VersionTrue  versionValue = 1
	VersionRaw   versionValue = 2
)

const strRawVersion string = "raw"

func (v *versionValue) IsBoolFlag() bool {
	return true
}

func (v *versionValue) Get() interface{} {
	return v
}

// 这个方法是为了实现 pflag.Value 接口
func (v *versionValue) Set(s string) error {
	if s == strRawVersion {
		*v = VersionRaw
		return nil
	}

	boolVar, err := strconv.ParseBool(s)
	if boolVar {
		*v = VersionTrue
	} else {
		*v = VersionFalse
	}
	return err
}

// 这个方法是为了实现 pflag.Value 接口
func (v *versionValue) String() string {
	if *v == VersionRaw {
		return strRawVersion
	}

	return fmt.Sprintf("%v", bool(*v == VersionTrue))
}

// 这个方法是为了实现 pflag.Value 接口
func (v *versionValue) Type() string {
	return "version"
}

const versionFlagName = "version"

// 定义 version 选项，获取选项值
var versionFlag = Version(versionFlagName, VersionFalse, "Print version information and quit.")

func Version(name string, value versionValue, usage string) *versionValue {
	// 使用自定义的 pflag.Value 实现类型
	pflag.Var(&value, name, usage)
	// 这里设置在命令行提供了选项但没指定值时的默认值
	pflag.Lookup(name).NoOptDefVal = "true"
	pflag.Lookup(name).DefValue = "false"
	return &value
}

func AddVersionFlag(fs *pflag.FlagSet) {
	fs.AddFlag(pflag.Lookup(versionFlagName))
}

// PrintAndExitIfReqested 打印版本信息并退出程序
func PrintAndExitIfReqested() {
	if *versionFlag == VersionTrue {
		fmt.Printf("%s\n", Get())
		os.Exit(0)
	} else if *versionFlag == VersionRaw {
		fmt.Printf("%#v\n", Get())
		os.Exit(0)
	}
}
